//
// Created by lw on 2020/3/2.
//
#include <iostream>
#include "native.h"
#include "inlineHook.h"
#include "And64InlineHook.hpp"

using namespace std;

#define TAG "dumpDex->"

#define DEBUG 1 //日志开关，1为开，其它为关
#if(DEBUG == 1)
    #define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, "[%s:%d]", fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__);
    #define LOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, TAG, "[%s:%d]", fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__);
    #define LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, TAG, "[%s:%d]", fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__);
    #define LOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, TAG, "[%s:%d]", fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
    #define LOGV(...) NULL
    #define LOGD(...) NULL
    #define LOGI(...) NULL
    #define LOGE(...) NULL
#endif

extern "C" void Java_com_xiaolong_sojiaziademo_Native_dump(JNIEnv *env, jobject obj, jstring packageName) {
    LOGI("1");
    LOGI("dumpdex >> c+++ 原吗");
    static bool is_hook = false;
    LOGI("2");
    char *p = (char *) env->GetStringUTFChars(packageName, 0);
    LOGI("3");
    __android_log_print(ANDROID_LOG_ERROR, TAG, "%s", p);
    if (is_hook) {
        LOGI("4");
        LOGI("hooked ignore");
        return;
    }
    LOGI("5");
    init_package_name(p);
    LOGI("6");
    env->ReleaseStringChars(packageName, (const jchar *) p);
    LOGI("7");
    ndk_init(env);
    LOGI("8");
    void *handle = ndk_dlopen("libart.so", RTLD_NOW);
    LOGI("9");
    if (handle == NULL) {
        LOGI("10");
        __android_log_print(ANDROID_LOG_ERROR, TAG, "Error: unable to find the SO : libart.so");
        return;
    }
    void *open_common_addr = ndk_dlsym(handle, get_open_function_flag());
    LOGI("11");
    if (open_common_addr == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "Error: unable to find the Symbol : ");
        LOGI("12");
        return;
    }
    LOGI("13");
#if defined(__aarch64__)
    LOGI("14");
    LOGI("start loaded so: libart.so");
    A64HookFunction(open_common_addr, get_new_open_function_addr(), get_old_open_function_addr());
    LOGI("end loaded so: libart.so");
    LOGI("15");
#elif defined(__arm__)
    LOGI("15 __arm__ ");
    if (registerInlineHook((uint32_t) open_common_addr, (uint32_t) get_new_open_function_addr(),
                           (uint32_t **) get_old_open_function_addr()) != ELE7EN_OK) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "register1 hook failed!");
        return;
    } else {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "register1 hook success!");
    }
    if (inlineHook((uint32_t) open_common_addr) != ELE7EN_OK) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "register2 hook failed!");
        return;
    } else {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "register2 hook success!");
    }
    __android_log_print(ANDROID_LOG_DEFAULT, TAG, "loaded so: libart.so");
#endif
    LOGI("16");
    LOGI("hook init complete");
    is_hook = true;
    LOGI("17");
}